package darknet.application.filesharing.impl;

import darknet.application.filesharing.impl.net.FileSharingProtocol;
import darknet.application.filesharing.impl.net.FileSharingProtocolHandler;
import darknet.application.filesharing.impl.net.FileSharingProtocolSender;
import darknet.application.filesharing.spec.FileSharingApplication;
import darknet.application.filesharing.spec.Release;
import darknet.application.filesharing.spec.SharedReleaseInformation;
import darknet.core.spec.net.NetworkManager;
import darknet.core.spec.net.Node;
import darknet.core.spec.net.Protocol;
import darknet.core.spec.net.ProtocolHandler;
import darknet.core.spec.net.ProtocolSender;

import java.io.File;
import java.util.HashSet;
import java.util.Set;

/**
 * File sharing application implementation.
 * 
 * @author yoyo
 */
public class FileSharingApplicationImpl implements FileSharingApplication {

    /** Shared releases */
    private Set<Release> releases = null;

    /** Network manager to use */
    private NetworkManager networkManager = null;

    /** Message handler */
    private FileSharingProtocolHandler handler = null;
    
    /** Message sender */
    private FileSharingProtocolSender sender = null;

    /**
     * Initialize a new File Sharing Application.
     *
     * @param networkManager The network manager to use.
     */
    public FileSharingApplicationImpl(NetworkManager networkManager) {

        if (networkManager == null) {
            throw new IllegalArgumentException("networkManger is null");
        }
        this.networkManager = networkManager;

        releases = new HashSet<Release>();
        handler = new FileSharingProtocolHandler();
        sender = new FileSharingProtocolSender();
    }

    @Override
    public Release makeRelease(File fileOrDirectory) {
        throw new UnsupportedOperationException("Not supported yet."); // TODO
    }

    @Override
    public void shareRelease(Release toShare) {

        if (toShare == null) {
            throw new IllegalArgumentException("toShare is invalid (null)");
        }

        // Add the release to the set of shared releases.
        releases.add(toShare);
    }

    @Override
    public void unshareRelease(Release toUnshare) {

        if (toUnshare == null) {
            throw new IllegalArgumentException("toShare is invalid (null)");
        }

        // remove the release to the set of shared releases.
        releases.remove(toUnshare);
    }

    @Override
    public Release[] getSharedReleases() {

        Release[] toArray = new Release[releases.size()];
        return releases.toArray(toArray);
    }

    @Override
    public SharedReleaseInformation getSharedReleaseInfo() {
        throw new UnsupportedOperationException("Not supported yet."); // TODO
    }

    @Override
    public Protocol getProtocol() {
        return FileSharingProtocol.getCurrent();
    }

    @Override
    public NetworkManager getNetworkManager() {
        return networkManager;
    }

    @Override
    public ProtocolHandler getHandler() {
        return handler;
    }

    @Override
    public ProtocolSender getSender() {
        return sender;
    }

    @Override
    public Set<Node> getReachableNodes() {

        // XXX Assuming that all nodes of your network have installed the
        // file sharing plugin
        return new HashSet<Node>(networkManager.getOnlineNodes());
    }
}
